# -*- coding: utf-8 -*-
# created on 2016/10/27

from sympy import log, Add, Mul, Pow
from mathsolver.functions.base.base import BaseFunction
from mathsolver.functions.base.objects import base_gen, BaseIneqs


class MiHanShuDingYiQiuCan(BaseFunction):
    def solver(self, *args):
        """
        通过幂函数的定义求输入含参解析式f(x)*x**g(x)+h(x)的参数。幂函数：x**a（a为常数且不为0）
        :param args: [0] - BaseFunc 含参解析式
        :return: base_gen
        """
        expr = args[0].expression
        sym = args[0].var
        p = self.recursively_get_power(expr, sym)
        coe = expr.coeff(p)
        plus = expr - coe * p
        genlist = []
        if coe != 1:
            genlist.append([coe, 1])
        judge = 0
        for i in expr.free_symbols:
            if i != sym:
                if plus.has(i) and (judge & 1) == 0:
                    genlist.append([plus, 0])
                    judge |= 0x01
                if p.args[1].has(i) and (judge & 2) == 0:
                    genlist.append([p.args[1], '!=', 0])
                    judge |= 0x02
        gen = base_gen(genlist)
        genlist = gen.value
        if isinstance(genlist[0], list):
            for eqorineq in genlist:
                if len(eqorineq) == 2:
                    eqorineq.insert(1, '=')
        else:
            if len(genlist) == 2:
                genlist.insert(1, '=')
        gen = BaseIneqs(genlist)
        self.steps.append(["由于f(x)是幂函数，根据幂函数的定义，如下条件恒成立：", gen.printing()])
        self.output.append(gen)
        self.label.add("幂函数的定义求参数")
        return self

    def recursively_get_power(self, expr, sym):
        if expr.is_Number or expr.is_Symbol:
            return None
        if isinstance(expr, Pow) and expr.args[0] == sym:
            if expr.args[1].has(sym):
                return None
            return expr
        elif isinstance(expr, Add) or isinstance(expr, Mul):
            for i in expr.args:
                result = self.recursively_get_power(i, sym)
                if result is not None:
                    return result
        return None


class ZhiShuHanShuDingYiQiuCan(BaseFunction):
    def solver(self, *args):
        """
        通过指数函数的定义求输入含参解析式f(x)*g(x)**x+h(x)的参数。指数函数：a**x（a为常数且a>0&&a!=1）
        :param args: [0] - BaseFunc 含参解析式
        :return: base_gen
        """
        expr = args[0].expression
        sym = args[0].var
        e = self.recursively_get_exponent(expr, sym)
        coe = expr.coeff(e)
        plus = expr - coe * e
        genlist = []
        if coe != 1:
            genlist.append([coe, 1])
        judge = 0
        for i in expr.free_symbols:
            if i != sym:
                if plus.has(i) and (judge & 1) == 0:
                    genlist.append([plus, 0])
                    judge |= 0x01
                if e.args[0].has(i) and (judge & 2) == 0:
                    genlist.append([e.args[0], '>', 0])
                    genlist.append([e.args[0], '!=', 1])
                    judge |= 0x02
        gen = base_gen(genlist)
        genlist = gen.value
        if isinstance(genlist[0], list):
            for eqorineq in genlist:
                if len(eqorineq) == 2:
                    eqorineq.insert(1, '=')
        else:
            if len(genlist) == 2:
                genlist.insert(1, '=')
        gen = BaseIneqs(genlist)
        self.steps.append(["由于f(x)是指数函数，根据幂函数的定义，如下条件恒成立：", gen.printing()])
        self.output.append(gen)
        self.label.add("指数函数的定义求参数")
        return self

    def recursively_get_exponent(self, expr, sym):
        if expr.is_Number or expr.is_Symbol:
            return None
        if isinstance(expr, Pow):
            if expr.args[1] == sym:
                return expr
            return None
        elif isinstance(expr, Add) or isinstance(expr, Mul):
            for i in expr.args:
                result = self.recursively_get_exponent(i, sym)
                if result is not None:
                    return result
        return None


class DuiShuHanShuDingYiQiuCan(BaseFunction):
    def solver(self, *args):
        """
        通过对数函数的定义求输入含参解析式f(x)*log(x,a)+h(x)的参数。指数函数：log(x,a)（a为常数且a>0&&a!=1）
        :param args: [0] - BaseFunc 含参解析式
        :return: base_gen
        """
        expr = args[0].expression
        sym = args[0].var
        coe = expr.coeff(log(sym))
        plus = expr - coe * log(sym)
        genlist = [[coe.args[0].args[0], '>', 0], [coe.args[0].args[0], '!=', 1]]
        for i in expr.free_symbols:
            if i != sym:
                if plus.has(i):
                    genlist.append([plus, 0])
                    break
        gen = base_gen(genlist)
        genlist = gen.value
        if isinstance(genlist[0], list):
            for eqorineq in genlist:
                if len(eqorineq) == 2:
                    eqorineq.insert(1, '=')
        else:
            if len(genlist) == 2:
                genlist.insert(1, '=')
        gen = BaseIneqs(genlist)
        self.steps.append(["由于f(x)是对数函数，根据幂函数的定义，如下条件恒成立：", gen.printing()])
        self.output.append(gen)
        self.label.add("对数函数的定义求参数")
        return self


if __name__ == '__main__':
    pass
